﻿using Gecko;
using MarkdEdit.markdown;
using Markdig;
using System;
using System.IO;
using System.Windows.Forms;

namespace MarkdEdit
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            this.Text = "MarkdEdit_geckofx";
            this.ShowIcon = false;
            this.StartPosition = FormStartPosition.CenterScreen;
            InitBrowser();

            this.Load += MainForm_Load;
            this.FormClosing += MainForm_FormClosing;
            SetAutoRender(true);
        }

        #region 环境初始化

        public const string TempDataDir = ".markdEdit";
        public static string DataDir;
        private static string HtmlFile;
        private MarkdownPipeline _pipeline;
        private StreamWriter _writer;

        private void MainForm_Load(object sender, EventArgs e)
        {
            var dir = Path.Combine(Application.StartupPath, TempDataDir);
            if (!Directory.Exists(dir))
            {
                var di = Directory.CreateDirectory(dir);
                di.Attributes = FileAttributes.Directory | FileAttributes.Hidden;
                CopyDir(Path.Combine(Application.StartupPath, "html"), Path.Combine(dir, "html"));
            }
            DataDir = dir;
            _pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().UseMathematics().UseGridTables().Build();
            HtmlFile = Path.Combine(DataDir, ".tData.html");
            if (File.Exists(HtmlFile))
            {
                File.Delete(HtmlFile);
            }
            _writer = new StreamWriter(File.OpenWrite(HtmlFile));
            this.richTextBox1.Text = CSSConsts.ExampleMath;
        }

        public static int CopyDir(string src, string des, bool corver = false)
        {
            try
            {
                //如果目标路径不存在,则创建目标路径
                if (!System.IO.Directory.Exists(des))
                {
                    System.IO.Directory.CreateDirectory(des);
                }
                //得到原文件根目录下的所有文件
                string[] files = System.IO.Directory.GetFiles(src);
                foreach (string file in files)
                {
                    string name = System.IO.Path.GetFileName(file);
                    string dest = System.IO.Path.Combine(des, name);
                    if (!File.Exists(dest) || corver)
                        System.IO.File.Copy(file, dest);//复制文件
                }
                //得到原文件根目录下的所有文件夹
                string[] folders = System.IO.Directory.GetDirectories(src);
                foreach (string folder in folders)
                {
                    string name = System.IO.Path.GetFileName(folder);
                    string dest = System.IO.Path.Combine(des, name);
                    CopyDir(folder, dest, corver);//构建目标路径,递归复制文件
                }
                return 1;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                return 0;
            }
        }

        private void RichTextBox1_TextChanged(object sender, EventArgs e)
        {
            Reload();
        }

        private void Reload()
        {
            var txt = this.richTextBox1.Text;
            var mdStr = txt;
            var htmlstr = Markdown.ToHtml(mdStr, _pipeline);
            var html = MarkDownDoc.WrapHtmlText_Math(htmlstr, CSSConsts.DefaultCss);
            _writer.Write(html);
            _writer.Flush();
            this.browser.LoadHtml(html, DataDir);
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            browser.Stop();
            browser.Dispose();
            _writer.Close();
            //Cef.Shutdown();
            Xpcom.Shutdown();
        }

        #endregion 环境初始化

        #region Cefsharp

        /*
         https://ourcodeworld.com/articles/read/173/how-to-use-cefsharp-chromium-embedded-framework-csharp-in-a-winforms-application
         */
        /*
         
        public ChromiumWebBrowser chromeBrowser;

        public void InitializeChromium()
        {
            CefSettings settings = new CefSettings();
            settings.LogFile = "log\\cef.log";
            settings.LogSeverity = LogSeverity.Error | LogSeverity.Fatal | LogSeverity.Warning;
            //settings.ResourcesDirPath = Application.StartupPath;
            settings.Locale = "zh-CN";
            settings.AcceptLanguageList = "zh-CN";
            settings.CachePath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "MarkdEdit", "cefCache");
            // Initialize cef with the provided settings
            Cef.Initialize(settings);
            // Create a browser component
            chromeBrowser = new ChromiumWebBrowser();
            // Add it to the form and fill it to the form window.
            this.panel_browser.Controls.Add(chromeBrowser);
            chromeBrowser.Dock = DockStyle.Fill;
            var setting = new BrowserSettings();
            setting.Javascript = CefState.Enabled;
            this.chromeBrowser.BrowserSettings = setting;
            this.chromeBrowser.FrameLoadEnd += ChromeBrowser_FrameLoadEnd;
        }

        private void ChromeBrowser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
        {
        }
        */

        #endregion Cefsharp

        #region GeckoWebBrowser 

        private GeckoWebBrowser browser;

        private void InitBrowser()
        {
            if (Environment.Is64BitProcess)
            {
                Xpcom.Initialize("Firefox64");
            }
            else
            {
                Xpcom.Initialize("Firefox");
            }
            browser = new GeckoWebBrowser();
            this.browser.Name = "browser";
            GeckoPreferences.User["gfx.font_rendering.graphite.enabled"] = true;//设置偏好：字体
            GeckoPreferences.User["privacy.donottrackheader.enabled"] = true;//设置浏览器不被追踪
            GeckoPreferences.User["intl.accept_languages"] = "zh-CN,zh;q=0.9,en;q=0.8";//不设置的话默认是英文区
            //GeckoPreferences.User["permissions.default.image"] = 2; //  block  image  禁止加载图片
            //GeckoPreferences.User["plugin.state.flash"] = 0;  // bloack flash禁止加载flash
            browser.CreateControl();
            //禁用右键菜单
            browser.NoDefaultContextMenu = true;
            browser.Dock = DockStyle.Fill;
            panel_browser.Controls.Add(browser);

            browser.ProgressChanged += Browser_ProgressChanged;
            //打开新窗口事件，全部设为在同一窗口打开
            browser.CreateWindow += Browser_CreateWindow;
            browser.DocumentCompleted += Browser_DocumentCompleted;
            //browser.UseHttpActivityObserver = true;//开启拦截请求
            //browser.ObserveHttpModifyRequest += Browser_ObserveHttpModifyRequest;//拦截请求（在创建窗口之前就拦截。）  
            //同时取消创建创建，在主窗口打开
            //browser.Navigate("http://www.baidu.com");
        }

        private void Browser_ProgressChanged(object sender, GeckoProgressEventArgs e)
        {
        }

        private void Browser_CreateWindow(object sender, GeckoCreateWindowEventArgs e)
        {
        }

        private void Browser_DocumentCompleted(object sender, Gecko.Events.GeckoDocumentCompletedEventArgs e)
        {
        }

        #endregion

        #region 主菜单

        private void tsb_showDevTool_Click(object sender, EventArgs e)
        {
            //显示开发者工具
            //this.browser.ShowDevTools();
        }

        private void tsb_refreshWeb_Click(object sender, EventArgs e)
        {
            this.browser.Reload();
        }

        #endregion 主菜单

        #region 工具栏菜单

        private void tsb_refresh_Click(object sender, EventArgs e)
        {
            Reload();
        }

        private void tsb_exportPDF_Click(object sender, EventArgs e)
        {
            var sf = new SaveFileDialog()
            {
                Title = "保存PDF",
                Filter = "PDF文件*.pdf|*.pdf"
            };
            if (sf.ShowDialog() == DialogResult.OK)
            {
                if (File.Exists(sf.FileName))
                    File.Delete(sf.FileName);
                this.browser.SaveDocument(sf.FileName);
                //var t = this.browser.PrintToPdfAsync(sf.FileName);
                //t.ContinueWith(r =>
                //{
                //    if (r.Result)
                //        MessageBox.Show("保存PDF完成", "提示");
                //    else
                //    {
                //        MessageBox.Show("保存失败:\n" + r.Exception.Message, "提示");
                //    }

                //});
            }
        }
        #endregion 工具栏菜单

        private void SetAutoRender(bool value)
        {
            this.richTextBox1.TextChanged -= RichTextBox1_TextChanged;
            if (value)
                this.richTextBox1.TextChanged += RichTextBox1_TextChanged;
        }

        private void 自动渲染ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var item = sender as ToolStripMenuItem;
            item.Checked = !item.Checked;
            SetAutoRender(item.Checked);
        }

        private void 普通表格ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.richTextBox1.Text = CSSConsts.ExampleGrid;
        }

        private void 数学公式ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.richTextBox1.Text = CSSConsts.ExampleMath;
        }

        private void 流程图ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.richTextBox1.Text = CSSConsts.ExampleFlow;
        }

        private void 普通文本ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.richTextBox1.Text = CSSConsts.ExampleNormal;
        }
    }
}